<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="哈希" tabindex="-1"><a class="header-anchor" href="#哈希"><span>哈希</span></a></h2>
<ul>
<li><a href="#introduction">介绍</a></li>
<li><a href="#configuration">设置</a></li>
<li><a href="#basic-usage">基础用法</a>
<ul>
<li><a href="#hashing-passwords">哈希密码</a></li>
<li><a href="#verifying-that-a-password-matches-a-hash">验证密码是否匹配哈希值</a></li>
<li><a href="#determining-if-a-password-needs-to-be-rehashed">确定密码是否需要重新哈希</a></li>
</ul>
</li>
<li><a href="#hash-algorithm-verification">哈希算法验证</a></li>
</ul>
<h2 id="介绍" tabindex="-1"><a class="header-anchor" href="#介绍"><span>介绍</span></a></h2>
<p>Laravel 的 Hash <a href="https://learnku.com/docs/laravel/11.x/facades" target="_blank" rel="noopener noreferrer">门面（facade）</a> 提供了安全的 Bcrypt 和 Argon2 哈希算法用于存储用户密码。如果你正在使用 <a href="https://learnku.com/docs/laravel/11.x/starter-kits" target="_blank" rel="noopener noreferrer">Laravel 应用起步套件</a> 之一，默认情况下将使用 Bcrypt 进行注册和身份验证。</p>
<p>Bcrypt 是一种很好的密码哈希选择，因为它的 「work factor」 是可调的，这意味着随着硬件性能的提升，生成哈希所需的时间也随之增加。在哈希密码时，速度较慢是有益的。算法花费更长时间来哈希密码，这意味着恶意用户用于针对应用程序的暴力攻击所生成所有可能的字符串哈希值的「彩虹表（rainbow tables）」所需的时间更长。</p>
<h2 id="设置" tabindex="-1"><a class="header-anchor" href="#设置"><span>设置</span></a></h2>
<p>默认情况下，Laravel 在哈希数据时使用 <code v-pre>bcrypt</code> 哈希驱动程序。但是，Laravel 还支持多种其他哈希驱动程序，包括 <a href="https://en.wikipedia.org/wiki/Argon2" target="_blank" rel="noopener noreferrer"><code v-pre>argon</code></a> 和 <a href="https://en.wikipedia.org/wiki/Argon2" target="_blank" rel="noopener noreferrer"><code v-pre>argon2id</code></a> 。</p>
<p>你可以使用 <code v-pre>HASH_DRIVER</code> 环境变量来指定应用程序的哈希驱动程序。但是，如果你想要自定义所有 Laravel 的哈希驱动选项，你应该使用 <code v-pre>config:publish</code> Artisan 命令来发布完整的 <code v-pre>hashing</code> 配置文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan config:publish hashing</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="基础用法" tabindex="-1"><a class="header-anchor" href="#基础用法"><span>基础用法</span></a></h2>
<h3 id="哈希密码" tabindex="-1"><a class="header-anchor" href="#哈希密码"><span>哈希密码</span></a></h3>
<p>你可以通过在 <code v-pre>Hash</code> 门面（facade）上调用 <code v-pre>make</code> 方法来对密码进行哈希处理：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>RedirectResponse</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Hash</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">PasswordController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 为用户更新密码</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">update</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">RedirectResponse</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// 校验新密码长度...</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">fill</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token property">newPassword</span><span class="token punctuation">)</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="调整-bcrypt-的工作因子" tabindex="-1"><a class="header-anchor" href="#调整-bcrypt-的工作因子"><span>调整 Bcrypt 的工作因子</span></a></h4>
<p>如果你正在使用 Bcrypt 算法，<code v-pre>make</code> 方法允许你使用 <code v-pre>rounds</code> 选项来管理算法的工作因子（work factor ）；然而，默认情况下 Laravel 管理的工作因子对大多数应用程序来说都是可以接受和适用的：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$hashed</span> <span class="token operator">=</span> <span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'rounds'</span> <span class="token operator">=></span> <span class="token number">12</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="调整-argon2-的工作因子" tabindex="-1"><a class="header-anchor" href="#调整-argon2-的工作因子"><span>调整 Argon2 的工作因子</span></a></h4>
<p>如果你正在使用 Argon2 算法，<code v-pre>make</code> 方法允许你使用 <code v-pre>memory</code>、<code v-pre>time</code> 和 <code v-pre>threads</code> 选项来管理算法的工作因子（work factor ）；然而，默认情况下 Laravel 管理的这些默认值对大多数应用程序来说也是可以接受和适用的：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$hashed</span> <span class="token operator">=</span> <span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'memory'</span> <span class="token operator">=></span> <span class="token number">1024</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'time'</span> <span class="token operator">=></span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'threads'</span> <span class="token operator">=></span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>[!NOTE]<br>
有关这些选项的更多信息，请参考 <a href="https://secure.php.net/manual/en/function.password-hash.php" target="_blank" rel="noopener noreferrer">官方 PHP 文档关于 Argon 哈希的内容</a>.</p>
</blockquote>
<h3 id="验证密码是否匹配哈希值" tabindex="-1"><a class="header-anchor" href="#验证密码是否匹配哈希值"><span>验证密码是否匹配哈希值</span></a></h3>
<p><code v-pre>Hash</code> 门面（facade）提供的 <code v-pre>check</code> 方法允许你验证给定的明文字符串是否对应于给定的哈希值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">check</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'plain-text'</span><span class="token punctuation">,</span> <span class="token variable">$hashedPassword</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 密码匹配...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="确定密码是否需要重新哈希" tabindex="-1"><a class="header-anchor" href="#确定密码是否需要重新哈希"><span>确定密码是否需要重新哈希</span></a></h3>
<p><code v-pre>Hash</code> 门面（facade）提供的 <code v-pre>needsRehash</code> 方法允许你确定自从密码被哈希后，哈希器使用的工作因子（work factor）是否发生了变化。一些应用会选择在认证过程中执行此检查：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">needsRehash</span><span class="token punctuation">(</span><span class="token variable">$hashed</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$hashed</span> <span class="token operator">=</span> <span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'plain-text'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="哈希算法验证" tabindex="-1"><a class="header-anchor" href="#哈希算法验证"><span>哈希算法验证</span></a></h2>
<p>为防止哈希算法被篡改，Laravel 的 <code v-pre>Hash::check</code> 方法会首先验证给定的哈希是否是使用应用程序选择的哈希算法生成的。如果算法不同，将会抛出 <code v-pre>RuntimeException</code> 异常。</p>
<p>大多数应用不希望哈希算法发生变化，因为出现不同的算法可能表明存在恶意攻击，这是大多数应用的一种预防机制。然而，如果你需要在应用程序内支持多种哈希算法，例如在从一种算法迁移至另一种算法时，你可以通过将 <code v-pre>HASH_VERIFY</code> 环境变量设置为 <code v-pre>false</code> 来禁用哈希算法的验证：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token key attr-name">HASH_VERIFY</span><span class="token punctuation">=</span><span class="token value attr-value">false</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/11.x/hashingmd/16694" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/ha...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/11.x/hashingmd/16694" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/ha...</a></p>
</blockquote>
</div></template>


